import java.util.*;

/**
 * 937. 重新排列日志文件
 * https://leetcode-cn.com/problems/reorder-data-in-log-files/
 */
public class Solutions_937 {
    public static void main(String[] args) {
        String[] logs = {"a1 9 2 3 1", "g1 act car", "zo4 4 7",
                "ab1 off key dog", "a8 act zoo"};
        // output: {"g1 act car", "a8 act zoo", "ab1 off key dog", "a1 9 2 3 1", "zo4 4 7"}

        String[] result = reorderLogFiles2(logs);
        System.out.println(Arrays.toString(result));
    }

    /**
     * 解法二：分别记录字母日志到字母列表，数字日志到数字列表，
     * 仅对字母日志进行排序
     * @param logs
     * @return
     */
    public static String[] reorderLogFiles2(String[] logs) {
        // 记录字母日志
        List<String> llist = new ArrayList<>();
        // 记录数字日志
        List<String> nlist = new ArrayList<>();

        for (String log : logs) {
            int idx = log.indexOf(" ");
            if (Character.isDigit(log.charAt(idx + 1))) {
                // 是数字
                nlist.add(log);
            } else {
                // 是字母
                llist.add(log);
            }
        }

        // 对字母日志进行排序
        Collections.sort(llist, (log1, log2) -> {
            // 排序规则：
            // 字母日志 在内容不同时，忽略标识符后，按内容字母顺序排序；
            // 在内容相同时，按标识符排序；
            // 1. 获取到日志内容
            int idx1 = log1.indexOf(" ");
            int idx2 = log2.indexOf(" ");
            String content1 = log1.substring(idx1 + 1);
            String content2 = log2.substring(idx2 + 1);

            if (content1.equals(content2)) {
                // 内容相同
                return log1.substring(0, idx1).compareTo(log2.substring(0, idx2));
            } else {
                // 内容不同，按照标识符排序
                return content1.compareTo(content2);
            }
        });
        List<String> res = new ArrayList<>();
        res.addAll(llist);
        res.addAll(nlist);
        return res.toArray(new String[res.size()]);
    }

    /**
     * 解法一：直接排序
     */
    public static String[] reorderLogFiles(String[] logs) {
        // 排序规则：
        // 1.所有 字母日志 都排在 数字日志 之前。
        // 2.字母日志 在内容不同时，忽略标识符后，按内容字母顺序排序；在内容相同时，按标识符排序；
        // 3.数字日志 应该按原来的顺序排列。
        Arrays.sort(logs, new Comparator<String>() {
            @Override
            public int compare(String log1, String log2) {
                // 根据空格，将字符串分割成两部分
                String[] split1 = log1.split(" ", 2);
                String[] split2 = log2.split(" ", 2);
                // 根据分割后的后一部分的第一个字符，判断是数字日志还是字母日志
                boolean isDigit1 = Character.isDigit(split1[1].charAt(0));
                boolean isDigit2 = Character.isDigit(split2[1].charAt(0));

                if (!isDigit1 && !isDigit2) {
                    // 两个都是字母日志，
                    int flag = split1[1].compareTo(split2[1]);
                    if (flag != 0) {
                        // 内容不同时，按内容排序
                        return flag;
                    } else {
                        // 内容相同时，按标识符排序
                        return split1[0].compareTo(split2[0]);
                    }
                } else if (isDigit1 && isDigit2) {
                    // 两个都是数字日志，保持相对顺序
                    return 0;
                } else {
                    // 其中一个是字母日志，一个是数字日志，字母日志在后
                    // 数字日志在后，字母日志在前
                    return isDigit1 ? 1 : -1;
                }
            }
        });
        return logs;
    }
}
